#include "stack.h"

/* ********* Prototype ********* */
/* *** Konstruktor/Kreator *** */
void CreateEmpty (Stack *S)
/* I.S. Sembarang */
/* F.S. Membuat sebuah stack S yang kosong berkapasitas MaxEl */
/* jadi indeksnya antara 1..MaxEl */
/* Ciri stack kosong : TOP bernilai Nil */
{
	TOP(*S) = Nil;
}

/* *** Prototype manajemen memori *** */
void Alokasi (address *P, infotype X)
/* I.S. P Sembarang, X terdefinisi */
/* F.S. Alamat P dialokasi, jika berhasil maka Info(P) = X dan Next(P) = Nil */
/*      P = Nil jika alokasi gagal */
{
	(*P) = Nil;
	(*P) = (address)malloc(sizeof(infotype));
	
	if ((*P) != Nil)
	{
		Info(*P) = X;
		Next(*P) = Nil;
	}
}

void Dealokasi (address *P)
/* I.S. P adalah hasil alokasi, P <> Nil */
/* F.S. Alamat P didealokasi, dikembalikan ke sistem */
{
	free(*P);
}

/* ********* Predikat Untuk test keadaan KOLEKSI ********* */
boolean IsEmpty (Stack S)
/* Mengirim true jika Stack kosong: lihat definisi di atas */
{
	return (TOP(S) == Nil);
}

/* ********** Operator Dasar Stack ********* */
void Push (Stack *S, infotype X)
/* Menambahkan X sebagai elemen Stack S. */
/* I.S. S mungkin kosong, tabel penampung elemen stack TIDAK penuh */
/* F.S. X menjadi TOP yang baru, TOP bertambah 1 */
{
	address P, Top;
	
	Alokasi(&P,X);
	
	if (P != Nil)
	{
		Top = TOP(*S);
		Next(P) = Top;
		TOP(*S) = P;
	}
}

void Pop (Stack *S, infotype *X)
/* Menghapus X dari Stack S. */
/* I.S. S  tidak kosong */
/* F.S. X adalah nilai elemen TOP yang lama, TOP berkurang 1 */
{
	address P;
	
	(*X) = InfoTop(*S);
	P = TOP(*S);
	TOP(*S) = Next(P);
	Dealokasi(&P);
}

void CopyStack (Stack * s1,Stack s2) {
    infotype c;
    Stack dummy;
    CreateEmpty(&dummy);
    DeleteStack(s1);

    while (!IsEmpty(s2)) {
        Pop(&s2,&c);
        Push(&dummy,c);
    }

    while (!IsEmpty(dummy)) {
        Pop(&dummy,&c);
        Push(s1,c);
        Push(&s2,c);
    }
    PrintStack(*s1);
    //Pop(s1,&c);
}

void DeleteStack (Stack * s) {
    infotype c;
    CreateEmpty(s);
    //while (!IsEmpty(*s)) {
    //    printf("a\n");
    //    Pop(s,&c);
    //}
}

boolean IsSameStack (Stack s1, Stack s2) {
    char c1,c2;
    Stack dum1, dum2;
    CreateEmpty(&dum1);
    CreateEmpty(&dum2);
    boolean found = true;
    while (!IsEmpty(s1) && !IsEmpty(s2) && found) {
        Pop(&s1,&c1);
        Pop(&s2,&c2);
        if (c2 != c1) {
            found = false;
        }
        Push(&dum1,c1);
        Push(&dum2,c2);
        
    }

    if (IsEmpty(s1) && (!IsEmpty(s2))) {
        found = false;
    } else if  ((!IsEmpty(s1)) && IsEmpty(s2)) {
        found = false;
    }

    while(!IsEmpty(dum1)) {
        Pop(&dum1,&c1);
        Push(&s1,c1);
    }

    while(!IsEmpty(dum2)) {
        Pop(&dum2,&c2);
        Push(&s2,c2);
    }

    return found;
}

void PrintStack (Stack s) {
    char c;
    Stack dum;
    CreateEmpty(&dum);

    while (!IsEmpty(s)) {
        Pop(&s,&c);
        printf("%c\n",c);
        Push(&dum,c);
    }

    while (!IsEmpty(dum)) {
        Pop(&dum,&c);
        Push(&s,c);
    }
}